﻿using adb;
using Masuit.Tools;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.EntityFrameworkCore;
using NPOI.OpenXmlFormats.Wordprocessing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using utils;

namespace Notication.AppCode
{
    /// <summary>
    ///  计算统计
    /// </summary>
    public static class StatisticsUtils 
    {
        public static DateTime t = DateTime.Now;

        private static adb.dbBase db = new adb.dbBase();


        public static async Task Power(DateTime t, Boolean logview = true)
        {
            using (var conn = db.CreateDeviceDb())
            {

                var oldlist = await conn.tStatisticsData.Where(x => x.statisticsDataDate == t).ToListAsync();
                var privateDataList = await conn.tAnalogData.Where(x => t <= x.addTime && x.addTime < t.AddMinutes(30)).ToListAsync();

                //WSR系列机组模拟量添加至统计list
                var privateDataList_WSR = await conn.tAnalogData_WSR.Where(x => t <= x.addTime && x.addTime < t.AddMinutes(30)).ToListAsync();
                var privateDataList1 = privateDataList_WSR.Select(item =>
                {
                    return new tAnalogData
                    {
                        addTime = item.addTime,
                        Topic = item.Topic,
                        analog9 = item.analog9,
                        analog10 = item.analog10
                    };
                });
                privateDataList.AddRange(privateDataList1);

                var publicDataList = await conn.tPublicAnalogData.Where(x => t <= x.addTime && x.addTime < t.AddMinutes(30)).ToListAsync();

                //WSR系列公共模拟量添加至统计list
                var publicDataList_WSR = await conn.tPublicAnalogData_WSR.Where(x => t <= x.addTime && x.addTime < t.AddMinutes(30)).ToListAsync();
                var publicDataList1 = publicDataList_WSR.Select(item =>
                {
                    return new tPublicAnalogData
                    {
                        addTime = item.addTime,
                        Topic = item.Topic,
                        p_analog33 = item.p_analog33,
                        p_analog35 = item.p_analog35,
                        p_analog37 = item.p_analog37
                    };
                });
                publicDataList.AddRange(publicDataList1);

                using (var connDb = db.CreateMyDb())
                {
                    var pdl = await connDb.tPowerStationDevice.Where(x => x.deviceType_keyId_fk == 820094 && x.dataState == 0).ToListAsync();
                    foreach (var deviceModel in pdl)
                    {
                        try
                        {
                            var devicePublicModel = await connDb.tPowerStationDevice.FirstOrDefaultAsync(x => x.devicePowerStation_powerStationId_fk == deviceModel.devicePowerStation_powerStationId_fk && x.deviceType_keyId_fk == 820097 && x.dataState == 0);
                            //此处应continue 用break当某电站无公共模拟量主题后面电站会break导致后面电站无法统计
                            if (devicePublicModel == null)
                                continue;
                            var oldModel = oldlist.Where(x => x.statisticsStation_powerStationId_fk == deviceModel.devicePowerStation_powerStationId_fk && x.deviceGroup == deviceModel.deviceGroup && x.statisticsDataDate == t).FirstOrDefault() ?? new tStatisticsData()
                            {
                                deviceGroup = deviceModel.deviceGroup,
                                statisticsStation_powerStationId_fk = deviceModel.devicePowerStation_powerStationId_fk,
                                statisticsDataDate = t
                            };
                            if (oldModel.statisticsDataId == 0)
                            {
                                oldlist.Add(oldModel);
                            }
                            oldModel.power = power(publicDataList, deviceModel.deviceGroup, devicePublicModel.deviceTopic);
                            oldModel.salePower = salePower(publicDataList, deviceModel.deviceGroup, devicePublicModel.deviceTopic);
                            oldModel.factoryUsePower = factoryUsePower(publicDataList, deviceModel.deviceGroup, devicePublicModel.deviceTopic);
                            if (logview)
                            {
                                Console.WriteLine($"{t} 至 {t.AddMinutes(30)}{devicePublicModel.deviceTopic} {deviceModel.deviceGroup}为:{oldModel.power}");
                            }
                            //计算高峰,低俗,平期发电量
                            {
                                var typeTimeList = await connDb.vGenerateElctricityTypeTime.Where(x => x.dateStart <= t && t <= x.dateEnd).ToListAsync();
                                foreach (var typeTimeItem in typeTimeList)
                                {
                                    typeTimeItem.timeStart = DateTime.Parse($"{t:yyyy-MM-dd} {typeTimeItem.timeStart:HH:mm:ss}");
                                    typeTimeItem.timeEnd = DateTime.Parse($"{t:yyyy-MM-dd} {typeTimeItem.timeEnd:HH:mm:ss}");
                                    if (typeTimeItem.geType == 1)
                                    {
                                        oldModel.highPower = GenerateElctricityTypeTime(publicDataList, devicePublicModel.deviceTopic, deviceModel.deviceGroup, typeTimeItem);
                                    }
                                    else if (typeTimeItem.geType == 2)
                                    {
                                        oldModel.flatPower = GenerateElctricityTypeTime(publicDataList, devicePublicModel.deviceTopic, deviceModel.deviceGroup, typeTimeItem);
                                    }
                                    else if (typeTimeItem.geType == 3)
                                    {
                                        oldModel.lowPower = GenerateElctricityTypeTime(publicDataList, devicePublicModel.deviceTopic, deviceModel.deviceGroup, typeTimeItem);
                                    }
                                }
                            }
                            oldModel.rainfall = 0;//电厂降雨量
                            oldModel.waterConsumption = 0;//耗水量

                            oldModel.activePower = activePower(privateDataList, deviceModel.deviceTopic);//机组有功功率
                            oldModel.buyPower = oldModel.factoryUsePower;//上网风电量
                            oldModel.runningCapacity = oldModel.activePower;//运行容量
                            oldModel.saleMoney = await priceAsync(connDb, deviceModel.devicePowerStation_powerStationId_fk);
                            oldModel.saleMoney = oldModel.salePower * oldModel.saleMoney;//卖电得钱
                            oldModel.reactivePower = reactivePower(privateDataList, deviceModel.deviceTopic);//无功功率
                            oldModel.powerGenerationTime = powerGenerationTime(privateDataList, deviceModel.deviceTopic);//发电时长
                        }
                        catch (Exception e)
                        {
                            writeExceptionLogUtil.writeLogException(e,"/root/logs","Notication");
                            Console.WriteLine(e.ToString());
                        }
                    }
                }
                var newList = oldlist.Where(x => x.statisticsDataId == 0).ToList();
                if (newList.Any())
                {
                    await conn.tStatisticsData.AddRangeAsync(newList);
                }
                await conn.SaveChangesAsync();
            }
        }
        /// <summary>
        /// 获取1号机组发电量
        /// </summary>
        /// <param name="groupName">机组标识</param>
        /// <returns></returns>
        public static decimal power(List<tPublicAnalogData> publicAnalogDatas, string groupName, string Topic)
        {
            var q = publicAnalogDatas.Where(x => x.Topic == Topic);
            if (q.Any() == false) return 0;
            if (groupName == "1#")
            {
                var max = q.Max(x => x.p_analog33);
                var min = q.Min(x => x.p_analog33);
                return (max - min) * 1200;
            }
            else if (groupName == "2#")
            {
                var max = q.Max(x => x.p_analog35);
                var min = q.Min(x => x.p_analog35);
                return (max - min) * 1200;
            }
            return 0;
        }
        /// <summary>
        /// 上网电量
        /// </summary>
        /// <param name="publicAnalogDatas"></param>
        /// <param name="groupName"></param>
        /// <returns></returns>
        public static decimal salePower(List<tPublicAnalogData> publicAnalogDatas, string groupName, string Topic)
        {
            var q = publicAnalogDatas.Where(x => x.Topic == Topic);
            if (q.Any() == false) return 0;
            if (groupName == "1#")
            {
                var max = q.Max(x => x.p_analog37);
                var min = q.Min(x => x.p_analog37);
                return (max - min) * 2000;
            }
            return 0;
        }
        /// <summary>
        /// 发电厂用电量
        /// </summary>
        /// <param name="publicAnalogDatas"></param>
        /// <param name="groupName"></param>
        /// <returns></returns>
        public static decimal factoryUsePower(List<tPublicAnalogData> publicAnalogDatas, string groupName, string Topic)
        {
            var q = publicAnalogDatas.Where(x => x.Topic == Topic);
            if (q.Any() == false) return 0;

            if (groupName == "1#")
            {

                var max = q.Max(x => x.p_analog37);
                var min = q.Min(x => x.p_analog37);
                var oneMax = q.Max(x => x.p_analog33);
                var oneMin = q.Min(x => x.p_analog33);
                var twoMax = q.Max(x => x.p_analog35);
                var twoMin = q.Min(x => x.p_analog35);
                return ((oneMax - oneMin) + (twoMax - twoMin)) * 1200 - (max - min) * 2000;
            }
            return 0;
        }
        /// <summary>
        /// 时段发电量
        /// </summary>
        /// <param name="publicAnalogDatas"></param>
        /// <param name="deviceTopic"></param>
        /// <param name="groupName"></param>
        /// <param name="typeTimeItem"></param>
        /// <returns></returns>
        public static decimal GenerateElctricityTypeTime(List<tPublicAnalogData> publicAnalogDatas, string deviceTopic, string groupName, vGenerateElctricityTypeTime typeTimeItem)
        {
            var q = publicAnalogDatas.Where(x => x.Topic == deviceTopic && typeTimeItem.timeStart <= x.addTime && x.addTime <= typeTimeItem.timeEnd);
            if (q.Any() == false) return 0;
            if (groupName == "1#")
            {
                var max = q.Max(x => x.p_analog37);
                var min = q.Min(x => x.p_analog37);
                return (max - min) * 2000;
            }
            return 0;
        }
        /// <summary>
        /// 有功功率
        /// </summary>
        /// <param name="analogDatas"></param>
        /// <param name="deviceTopic"></param>
        /// <returns></returns>
        public static decimal activePower(List<tAnalogData> analogDatas, string deviceTopic)
        {
            var activePowerList = analogDatas.Where(x => x.Topic == deviceTopic && x.analog9 > 0);
            if (activePowerList.Any() == false) return 0;
            return activePowerList.Any() ? activePowerList.Average(x => x.analog9) : 0;
        }
        /// <summary>
        /// 无功功率
        /// </summary>
        /// <param name="analogDatas"></param>
        /// <param name="deviceTopic"></param>
        /// <returns></returns>
        public static decimal reactivePower(List<tAnalogData> analogDatas, string deviceTopic)
        {
            if (analogDatas.Any(x => x.Topic == deviceTopic && x.analog10 > 0) == false) return 0;
            var activePowerList = analogDatas.Where(x => x.Topic == deviceTopic && x.analog10 > 0);
            return activePowerList.Any() ? activePowerList.Average(x => x.analog10) : 0;
        }
        /// <summary>
        /// 发电时长
        /// </summary>
        /// <param name="analogDatas"></param>
        /// <param name="deviceTopic"></param>
        /// <returns></returns>
        public static decimal powerGenerationTime(List<tAnalogData> analogDatas, string deviceTopic)
        {
            if (analogDatas.Any(x => x.Topic == deviceTopic && x.analog31 > 0) == false) return 0;
            var activePowerList = analogDatas.Where(x => x.Topic == deviceTopic && x.analog31 > 0);
            var min = activePowerList.Min(x => x.addTime);
            var max = activePowerList.Max(x => x.addTime);
            return (max - min).Value.TotalSeconds.ConvertTo<decimal>();
        }

        public static Dictionary<long, Tuple<DateTime, decimal>> priceDic = new Dictionary<long, Tuple<DateTime, decimal>>();
        /// <summary>
        /// 获取电站价格
        /// </summary>
        /// <param name="connDb"></param>
        /// <param name="powerStationId"></param>
        /// <returns></returns>
        public static async Task<decimal> priceAsync(MyDbContext connDb, long powerStationId)
        {
            if (priceDic.ContainsKey(powerStationId) && priceDic[powerStationId].Item1 > DateTime.Now)
            {
                return priceDic[powerStationId].Item2;
            }
            var price = (await connDb.tPowerStation.FirstOrDefaultAsync(x => x.powerStationId == powerStationId) ?? new tPowerStation()).upPrice;
            priceDic[powerStationId] = new Tuple<DateTime, decimal>(DateTime.Now.AddMinutes(5), price);
            return price;
        }




        public static async Task Power_new(DateTime t)
        {
            using (var connDb = db.CreateMyDb())
            {
                var powerStationList = await connDb.tPowerStation.Where(x => x.dataState == 0).ToListAsync();
                foreach (var powerStation in powerStationList)
                {
                   await doCalculatePower(t, powerStation);
                }
            }
        }

        public static async Task doCalculatePower(DateTime t, tPowerStation powerStation)
        {

            using (var connDb = db.CreateMyDb())
            {
                //var powerStation = connDb.tPowerStation.FirstOrDefault(x => x.powerStationId == powerStationId);
                //if (powerStation == null)
                //{
                //    return;
                //}
                var deviceSN = (await connDb.tDevice.FirstOrDefaultAsync(x => x.station_device_powerStationId_fk == powerStation.powerStationId && x.dataState == 0))?.deviceSN;
                if (string.IsNullOrEmpty(deviceSN))
                {
                    return;
                }
                Console.WriteLine($"开始统计电站 {powerStation.powerStationName}");

                var publicDataList = await get_publicDataList(deviceSN, t, powerStation.powerStationNo);
                var privateDataList = await get_privateDataList(deviceSN, t, powerStation.powerStationNo);

                //公共模拟量
                var devicePublicModel = await connDb.tPowerStationDevice.FirstOrDefaultAsync(x => x.devicePowerStation_powerStationId_fk == powerStation.powerStationId && x.deviceType_keyId_fk == 820097 && x.dataState == 0);
                decimal powerRate = powerStation.powerRate;
                decimal salePowerRate = powerStation.salePowerRate;

                using (var conn = db.CreateDeviceDb())
                {
                    var oldlist = await conn.tStatisticsData.Where(x => x.statisticsDataDate == t && x.statisticsStation_powerStationId_fk == powerStation.powerStationId).ToListAsync();

                    var pdl = await connDb.tPowerStationDevice.Where(x => x.deviceType_keyId_fk == 820094 && x.dataState == 0 && x.devicePowerStation_powerStationId_fk == powerStation.powerStationId).ToListAsync();

                    foreach (var deviceModel in pdl)
                    {
                        try
                        {
                            
                            //不为YKF1和YKF2系列 且公共模拟量主题空 跳过此条主题统计
                            if (devicePublicModel == null && deviceSN != "YKF1" && deviceSN != "YKF2")
                            {
                                Console.WriteLine($"电站{powerStation.powerStationName}无公共模拟量 跳过电站下主题");
                                break;
                            }

                            var oldModel = oldlist.Where(x => x.statisticsStation_powerStationId_fk == deviceModel.devicePowerStation_powerStationId_fk && x.deviceGroup == deviceModel.deviceGroup && x.statisticsDataDate == t).FirstOrDefault() ?? new tStatisticsData()
                            {
                                deviceGroup = deviceModel.deviceGroup,
                                statisticsStation_powerStationId_fk = deviceModel.devicePowerStation_powerStationId_fk,
                                statisticsDataDate = t
                            };

                            if (oldModel.statisticsDataId == 0)
                            {
                                oldlist.Add(oldModel);
                            }

                            //从机组模拟量统计电量 根据deviceSN区分倍率
                            if ("YKF1".Equals(deviceSN) || "YKF2".Equals(deviceSN) || "XAFD".Equals(deviceSN))
                            {
                                oldModel.power = powerByUnit(privateDataList, deviceModel.deviceGroup, deviceModel.deviceTopic, deviceSN, powerRate, salePowerRate);
                                oldModel.salePower = 0;
                                oldModel.factoryUsePower = 0;

                                Console.WriteLine($"{t} 至 {t.AddMinutes(30)}{deviceModel.deviceTopic} {deviceModel.deviceGroup}为:{oldModel.power}");

                                //计算高峰,低谷,平期发电量
                                {
                                    var typeTimeList = await connDb.vGenerateElctricityTypeTime.Where(x => x.dateStart <= t && t <= x.dateEnd && x.powerStation_powerStationId_fk == powerStation.powerStationId).ToListAsync();
                                    foreach (var typeTimeItem in typeTimeList)
                                    {
                                        typeTimeItem.timeStart = DateTime.Parse($"{t:yyyy-MM-dd} {typeTimeItem.timeStart:HH:mm:ss}");
                                        typeTimeItem.timeEnd = DateTime.Parse($"{t:yyyy-MM-dd} {typeTimeItem.timeEnd:HH:mm:ss}");
                                        if (typeTimeItem.geType == 1)
                                        {
                                            oldModel.highPower = GenerateElctricityTypeTimeByUnit_new(privateDataList, deviceModel.deviceTopic, deviceModel.deviceGroup, typeTimeItem, deviceSN, powerRate, salePowerRate);
                                        }
                                        else if (typeTimeItem.geType == 2)
                                        {
                                            oldModel.flatPower = GenerateElctricityTypeTimeByUnit_new(privateDataList, deviceModel.deviceTopic, deviceModel.deviceGroup, typeTimeItem, deviceSN, powerRate, salePowerRate);
                                        }
                                        else if (typeTimeItem.geType == 3)
                                        {
                                            oldModel.lowPower = GenerateElctricityTypeTimeByUnit_new(privateDataList, deviceModel.deviceTopic, deviceModel.deviceGroup, typeTimeItem, deviceSN, powerRate, salePowerRate);
                                        }
                                    }
                                }

                            }
                            else if ("wsr".Equals(deviceSN)) 
                            {
                                oldModel.power = powerByUnit(privateDataList, deviceModel.deviceGroup, deviceModel.deviceTopic, deviceSN, powerRate, salePowerRate);
                                oldModel.salePower = salePowerByPublic(publicDataList, deviceModel.deviceGroup, devicePublicModel.deviceTopic, deviceSN, powerRate, salePowerRate);

                                //有上网电量则计算厂用电量
                                if (oldModel.salePower > 0)
                                    oldModel.factoryUsePower = factoryUsePowerByUnit(publicDataList,privateDataList, deviceModel.deviceGroup, devicePublicModel.deviceTopic, deviceSN, powerRate, salePowerRate);

                                Console.WriteLine($"{t} 至 {t.AddMinutes(30)}{devicePublicModel.deviceTopic} {deviceModel.deviceGroup}为:{oldModel.power}");

                                //计算高峰,低谷,平期发电量
                                {
                                    var typeTimeList = await connDb.vGenerateElctricityTypeTime.Where(x => x.dateStart <= t && t <= x.dateEnd && x.powerStation_powerStationId_fk == powerStation.powerStationId).ToListAsync();
                                    foreach (var typeTimeItem in typeTimeList)
                                    {
                                        typeTimeItem.timeStart = DateTime.Parse($"{t:yyyy-MM-dd} {typeTimeItem.timeStart:HH:mm:ss}");
                                        typeTimeItem.timeEnd = DateTime.Parse($"{t:yyyy-MM-dd} {typeTimeItem.timeEnd:HH:mm:ss}");
                                        if (typeTimeItem.geType == 1)
                                        {
                                            oldModel.highPower = GenerateElctricityTypeTimeByUnit_new(privateDataList, devicePublicModel.deviceTopic, deviceModel.deviceGroup, typeTimeItem, deviceSN, powerRate, salePowerRate);
                                        }
                                        else if (typeTimeItem.geType == 2)
                                        {
                                            oldModel.flatPower = GenerateElctricityTypeTimeByUnit_new(privateDataList, devicePublicModel.deviceTopic, deviceModel.deviceGroup, typeTimeItem, deviceSN, powerRate, salePowerRate);
                                        }
                                        else if (typeTimeItem.geType == 3)
                                        {
                                            oldModel.lowPower = GenerateElctricityTypeTimeByUnit_new(privateDataList, devicePublicModel.deviceTopic, deviceModel.deviceGroup, typeTimeItem, deviceSN, powerRate, salePowerRate);
                                        }
                                    }
                                }
                            }
                            //从公共模拟量统计电量 根据deviceSN区分倍率
                            else
                            {
                                oldModel.power = powerByPublic(publicDataList, deviceModel.deviceGroup, devicePublicModel.deviceTopic, deviceSN, powerRate, salePowerRate);
                                oldModel.salePower = salePowerByPublic(publicDataList, deviceModel.deviceGroup, devicePublicModel.deviceTopic, deviceSN, powerRate, salePowerRate);
                                oldModel.factoryUsePower = factoryUsePowerByPublic(publicDataList, deviceModel.deviceGroup, devicePublicModel.deviceTopic, deviceSN, powerRate, salePowerRate);


                                Console.WriteLine($"{t} 至 {t.AddMinutes(30)}{devicePublicModel.deviceTopic} {deviceModel.deviceGroup}为:{oldModel.power}");

                                //计算高峰,低谷,平期发电量
                                {
                                    var typeTimeList = await connDb.vGenerateElctricityTypeTime.Where(x => x.dateStart <= t && t <= x.dateEnd && x.powerStation_powerStationId_fk == powerStation.powerStationId).ToListAsync();
                                    foreach (var typeTimeItem in typeTimeList)
                                    {
                                        typeTimeItem.timeStart = DateTime.Parse($"{t:yyyy-MM-dd} {typeTimeItem.timeStart:HH:mm:ss}");
                                        typeTimeItem.timeEnd = DateTime.Parse($"{t:yyyy-MM-dd} {typeTimeItem.timeEnd:HH:mm:ss}");
                                        if (typeTimeItem.geType == 1)
                                        {
                                            oldModel.highPower = GenerateElctricityTypeTimeByPublic(publicDataList, devicePublicModel.deviceTopic, deviceModel.deviceGroup, typeTimeItem, deviceSN, powerRate, salePowerRate);
                                        }
                                        else if (typeTimeItem.geType == 2)
                                        {
                                            oldModel.flatPower = GenerateElctricityTypeTimeByPublic(publicDataList, devicePublicModel.deviceTopic, deviceModel.deviceGroup, typeTimeItem, deviceSN, powerRate, salePowerRate);
                                        }
                                        else if (typeTimeItem.geType == 3)
                                        {
                                            oldModel.lowPower = GenerateElctricityTypeTimeByPublic(publicDataList, devicePublicModel.deviceTopic, deviceModel.deviceGroup, typeTimeItem, deviceSN, powerRate, salePowerRate);
                                        }
                                    }
                                }
                            }
                            oldModel.rainfall = 0;//电厂降雨量
                            oldModel.waterConsumption = 0;//耗水量

                            oldModel.activePower = activePower_new(privateDataList, deviceModel.deviceTopic);//机组有功功率
                            oldModel.buyPower = oldModel.factoryUsePower;//购电量 = 现场测的厂用电量
                            oldModel.runningCapacity = oldModel.activePower;//运行容量
                            oldModel.saleMoney = powerStation.upPrice;
                            oldModel.saleMoney = oldModel.salePower * oldModel.saleMoney;//卖电得钱
                            oldModel.reactivePower = reactivePower_new(privateDataList, deviceModel.deviceTopic);//无功功率
                            oldModel.powerGenerationTime = powerGenerationTime(privateDataList, deviceModel.deviceTopic);//发电时长
                        }
                        catch (Exception e)
                        {
                            writeExceptionLogUtil.writeLogException(e,"/root/logs","Notication");
                            Console.WriteLine(e.ToString());
                        }
                    }

                    var newList = oldlist.Where(x => x.statisticsDataId == 0).ToList();
                    if (newList.Any())
                    {
                        await conn.tStatisticsData.AddRangeAsync(newList);
                    }
                    await conn.SaveChangesAsync();

                    Console.WriteLine($"完成统计电站 {powerStation.powerStationName}");

                }
            }
        }

        /// <summary>
        /// 从机组模拟量计算机组发电量
        /// </summary>
        /// <param name="groupName">机组标识</param>
        /// <returns></returns>
        public static decimal powerByUnit(List<tAnalogData> analogDatas, string groupName, string Topic, string deviceSN, decimal powerRate = 1, decimal salePowerRate = 1)
        {

            var q = analogDatas.Where(x => x.Topic == Topic);
            if (q.Any() == false) return 0;
            //if (groupName == "1#")
            //{
            //    var max = q.Max(x => x.analog82);
            //    var min = q.Where(x => x.analog82 > 0).MinOrDefault(x => x.analog82);
            //    if (max.HasValue && min.HasValue)
            //        return (max.Value - min.Value) * powerRate;
            //    else
            //        return 0;
            //}
            //else if (groupName == "2#")
            //{
            //    var max = q.Max(x => x.analog82);
            //    var min = q.Where(x => x.analog82 > 0).MinOrDefault(x => x.analog82);
            //    if (max.HasValue && min.HasValue)
            //        return (max.Value - min.Value) * powerRate;
            //    else
            //        return 0;
            //}else
            {
                var max = q.MaxOrDefault(x => x.analog82);
                var min = q.Where(x => x.analog82 > 0).MinOrDefault(x => x.analog82);
                if (max.HasValue && min.HasValue)
                    return (max.Value - min.Value) * powerRate;
                else
                    return 0;
            }
            return 0;
        }

        /// <summary>
        ///从公共模拟量获取机组发电量
        /// </summary>
        /// <param name="groupName">机组标识</param>
        /// <returns></returns>
        public static decimal powerByPublic(List<tPublicAnalogData> publicAnalogDatas, string groupName, string Topic, string deviceSN, decimal powerRate = 1, decimal salePowerRate = 1)
        {
            var q = publicAnalogDatas.Where(x => x.Topic == Topic);
            if (q.Any() == false) return 0;
            if (groupName == "1#")
            {
                var max = q.Max(x => x.p_analog33);
                var min = q.Where(x => x.p_analog33 > 0).MinOrDefault(x => x.p_analog33);
                return (max - min) * powerRate;
            }
            else if (groupName == "2#")
            {
                var max = q.Max(x => x.p_analog35);
                var min = q.Where(x => x.p_analog35 > 0).MinOrDefault(x => x.p_analog35);
                return (max - min) * powerRate;
            }
            return 0;
        }

        /// <summary>
        /// 上网电量
        /// </summary>
        /// <param name="publicAnalogDatas"></param>
        /// <param name="groupName"></param>
        /// <returns></returns>
        public static decimal salePowerByPublic(List<tPublicAnalogData> publicAnalogDatas, string groupName, string Topic, string deviceSN, decimal powerRate = 1, decimal salePowerRate = 1)
        {
            var q = publicAnalogDatas.Where(x => x.Topic == Topic);
            if (q.Any() == false) return 0;
            if (groupName == "1#")
            {
                //if ("wsr".Equals(deviceSN))
                //{
                //    var max = q.Max(x => x.p_analog43);
                //    var min = q.Where(x => x.p_analog43 > 0).MinOrDefault(x => x.p_analog43);
                //    var oneMax = q.Max(x => x.p_analog33);
                //    var oneMin = q.Where(x => x.p_analog33 > 0).MinOrDefault(x => x.p_analog33);
                //    var twoMax = q.Max(x => x.p_analog35);
                //    var twoMin = q.Where(x => x.p_analog35 > 0).MinOrDefault(x => x.p_analog35);
                //    return ((oneMax - oneMin) + (twoMax - twoMin)) * powerRate - (max - min) * salePowerRate;   //上网电量 = 一二号机组发电量 - 厂用电量
                //}
                //else
                {
                    var max = q.Max(x => x.p_analog37);
                    var min = q.Where(x => x.p_analog37 > 0).MinOrDefault(x => x.p_analog37);      //37 上网电量
                    return (max - min) * salePowerRate;
                }
            }
            return 0;
        }
        /// <summary>
        /// 发电厂用电量
        /// </summary>
        /// <param name="publicAnalogDatas"></param>
        /// <param name="groupName"></param>
        /// <returns></returns>
        public static decimal factoryUsePowerByPublic(List<tPublicAnalogData> publicAnalogDatas, string groupName, string Topic, string deviceSN, decimal powerRate = 1, decimal salePowerRate = 1)
        {
            var q = publicAnalogDatas.Where(x => x.Topic == Topic);
            if (q.Any() == false) return 0;

            if (groupName == "1#")
            {
                //if ("wsr".Equals(deviceSN))
                //{
                //    var max = q.Max(x => x.p_analog43);
                //    var min = q.Where(x => x.p_analog43 > 0).MinOrDefault(x => x.p_analog43);      //42 厂用电量
                //    return (max - min) * salePowerRate;

                //}
                //else
                {
                    var max = q.Max(x => x.p_analog37);
                    var min = q.Where(x => x.p_analog37 > 0).MinOrDefault(x => x.p_analog37);
                    var oneMax = q.Max(x => x.p_analog33);
                    var oneMin = q.Where(x => x.p_analog33 > 0).MinOrDefault(x => x.p_analog33);
                    var twoMax = q.Max(x => x.p_analog35);
                    var twoMin = q.Where(x => x.p_analog35 > 0).MinOrDefault(x => x.p_analog35);
                    return ((oneMax - oneMin) + (twoMax - twoMin)) * powerRate - (max - min) * salePowerRate;
                }
            }
            return 0;
        }
        /// <summary>
        /// 从公共模拟量与机组发电量计算厂用电量
        /// </summary>
        /// <param name="publicAnalogDatas"></param>
        /// <param name="analogDatas"></param>
        /// <param name="groupName"></param>
        /// <param name="Topic"></param>
        /// <param name="deviceSN"></param>
        /// <param name="powerRate"></param>
        /// <param name="salePowerRate"></param>
        /// <returns></returns>
        public static decimal factoryUsePowerByUnit(List<tPublicAnalogData> publicAnalogDatas, List<tAnalogData> analogDatas, string groupName, string Topic, string deviceSN, decimal powerRate = 1, decimal salePowerRate = 1)
        {
            var q = publicAnalogDatas.Where(x => x.Topic == Topic);
            if (q.Any() == false) return 0;

            if (groupName == "1#")
            {
                //if ("wsr".Equals(deviceSN))
                //{
                //    var max = q.Max(x => x.p_analog43);
                //    var min = q.Where(x => x.p_analog43 > 0).MinOrDefault(x => x.p_analog43);      //42 厂用电量
                //    return (max - min) * salePowerRate;

                //}
                //else
                

                {
                    var max = q.Max(x => x.p_analog37);
                    var min = q.Where(x => x.p_analog37 > 0).MinOrDefault(x => x.p_analog37);

                    //计算当前时段每个机组的发电增量
                    var group_analog = analogDatas.GroupBy(x => x.Topic);
                    decimal countPower = 0;
                    foreach (var group in group_analog)
                    {
                        var group_max = group.MaxOrDefault(x => x.analog82)??0;
                        var group_min = group.Where(x => x.analog82 > 0).MinOrDefault(x => x.analog82)??0;
                        countPower += (group_max - group_min);
                    }
                    //var oneMax = q.Max(x => x.p_analog33);
                    //var oneMin = q.Where(x => x.p_analog33 > 0).MinOrDefault(x => x.p_analog33);
                    //var twoMax = q.Max(x => x.p_analog35);
                    //var twoMin = q.Where(x => x.p_analog35 > 0).MinOrDefault(x => x.p_analog35);
                    //var thirdMax = q.MaxOrDefault(x => x.p_analog52) ?? 0;
                    //var thirdMin = q.Where(x => x.p_analog52 > 0).MinOrDefault(x => x.p_analog52) ?? 0;
                    return (countPower) * powerRate - (max - min) * salePowerRate;
                }
            }
            return 0;
        }

        /// <summary>
        /// 有功功率
        /// </summary>
        /// <param name="analogDatas"></param>
        /// <param name="deviceTopic"></param>
        /// <returns></returns>
        public static decimal activePower_new(List<tAnalogData> analogDatas, string deviceTopic)
        {
            var activePowerList = analogDatas.Where(x => x.Topic == deviceTopic && x.analog31 > 0);
            if (activePowerList.Any() == false) return 0;
            return activePowerList.Any() ? activePowerList.Average(x => x.analog31) : 0;
        }
        /// <summary>
        /// 无功功率
        /// </summary>
        /// <param name="analogDatas"></param>
        /// <param name="deviceTopic"></param>
        /// <returns></returns>
        public static decimal reactivePower_new(List<tAnalogData> analogDatas, string deviceTopic)
        {
            if (analogDatas.Any(x => x.Topic == deviceTopic && x.analog32 > 0) == false) return 0;
            var activePowerList = analogDatas.Where(x => x.Topic == deviceTopic && x.analog32 > 0);
            return activePowerList.Any() ? activePowerList.Average(x => x.analog32) : 0;
        }


        /// <summary>
        /// 时段发电量
        /// </summary>
        /// <param name="publicAnalogDatas"></param>
        /// <param name="deviceTopic"></param>
        /// <param name="groupName"></param>
        /// <param name="typeTimeItem"></param>
        /// <returns></returns>
        public static decimal GenerateElctricityTypeTimeByUnit(List<tAnalogData> analogDatas, string deviceTopic, string groupName, vGenerateElctricityTypeTime typeTimeItem, string deviceSN, decimal powerRate = 1, decimal salePowerRate = 1)
        {
            var q = analogDatas.Where(x => x.Topic == deviceTopic && typeTimeItem.timeStart <= x.addTime && x.addTime <= typeTimeItem.timeEnd);
            if (q.Any() == false) return 0;
            if (groupName == "1#")
            {
                var max = q.Max(x => x.analog82);
                var min = q.Where(x => x.analog82 > 0).MinOrDefault(x => x.analog82);
                if (max.HasValue && min.HasValue)
                    return (max.Value - min.Value) * powerRate;
                else
                    return 0;
            }
            return 0;
        }

        /// <summary>
        /// 时段发电量
        /// </summary>
        /// <param name="publicAnalogDatas"></param>
        /// <param name="deviceTopic"></param>
        /// <param name="groupName"></param>
        /// <param name="typeTimeItem"></param>
        /// <returns></returns>
        public static decimal GenerateElctricityTypeTimeByPublic(List<tPublicAnalogData> publicAnalogDatas, string deviceTopic, string groupName, vGenerateElctricityTypeTime typeTimeItem, string deviceSN, decimal powerRate = 1, decimal salePowerRate = 1)
        {
            var q = publicAnalogDatas.Where(x => x.Topic == deviceTopic && typeTimeItem.timeStart <= x.addTime && x.addTime <= typeTimeItem.timeEnd);
            if (q.Any() == false) return 0;
            if (groupName == "1#")
            {
                    if ("wsr".Equals(deviceSN))
                    {
                        var max = q.Max(x => x.p_analog43);
                        var min = q.Where(x => x.p_analog43 > 0).MinOrDefault(x => x.p_analog43);
                        var oneMax = q.Max(x => x.p_analog33);
                        var oneMin = q.Where(x => x.p_analog33 > 0).MinOrDefault(x => x.p_analog33);
                        var twoMax = q.Max(x => x.p_analog35);
                        var twoMin = q.Where(x => x.p_analog35 > 0).MinOrDefault(x => x.p_analog35);
                        return ((oneMax - oneMin) + (twoMax - twoMin)) * powerRate - (max - min) * salePowerRate;   // 上网电量 = 一二号机组发电量 - 厂用电量
                    }
                    else
                    {
                        var max = q.Max(x => x.p_analog37);
                        var min = q.Where(x => x.p_analog37 > 0).MinOrDefault(x => x.p_analog37);
                        return (max - min) * salePowerRate;
                    }
            }
            return 0;
        }

        /// <summary>
        /// 获取公共部分analog数据
        /// </summary>
        /// <param name="sn"></param>
        /// <param name="t"></param>
        /// <param name="Interval"></param>
        /// <returns></returns>
        private async static Task<List<tPublicAnalogData>> get_publicDataList(string sn, DateTime t, string powerStationNo)
        {
            List<tPublicAnalogData> publicDataList = new List<tPublicAnalogData>();
            var topic = $"/{powerStationNo}/";

            using (var conn = db.CreateDeviceDb())
            {
                if ("wsr".Equals(sn))
                {
                    //WSR系列公共模拟量添加至统计list
                    var publicDataList_WSR = await conn.tPublicAnalogData_WSR.Where(x => t.AddMinutes(-30) <= x.addTime && x.addTime < t.AddMinutes(30) && x.Topic.Contains(topic)).ToListAsync();

                    //30分钟前电度数最大那一条加进来
                    //var publicDataList_WSR_MAX = publicDataList_WSR.Where(x => x.addTime < t).OrderByDescending(x => x.addTime).FirstOrDefault();

                    //30分钟前所属主题最大时间的list加进来
                    var privateDataList_WSR_MAX = new List<tPublicAnalogData_WSR>();
                    var privateDataList_WSR_topiclist = publicDataList_WSR.GroupBy(x => x.Topic).ToList();
                    foreach (var item in privateDataList_WSR_topiclist)
                    {
                        var top = publicDataList_WSR.Where(x => x.addTime < t && x.Topic == item.Key).OrderByDescending(x => x.addTime).FirstOrDefault();
                        if (top != null) privateDataList_WSR_MAX.Add(top);
                    }


                    publicDataList_WSR = publicDataList_WSR.Where(x => t <= x.addTime && x.addTime < t.AddMinutes(30)).ToList();

                    if (privateDataList_WSR_MAX.Count != 0)
                    {
                        publicDataList_WSR.AddRange(privateDataList_WSR_MAX);
                    }

                    var publicDataList1 = publicDataList_WSR.Select(item =>
                    {
                        return new tPublicAnalogData
                        {
                            addTime = item.addTime,
                            Topic = item.Topic,
                            p_analog33 = item.p_analog33,
                            p_analog35 = item.p_analog35,   
                            p_analog37 = item.p_analog37,
                        };
                    });
                    publicDataList.AddRange(publicDataList1);

                }
                else if ("HMTC".Equals(sn))
                {
                    publicDataList = await conn.tPublicAnalogData.Where(x => t.AddMinutes(-30) <= x.addTime && x.addTime < t.AddMinutes(30) && x.Topic.Contains(topic)).ToListAsync();

                    //30分钟前电度数最大那一条加进来
                    //var publicDataList_MAX = publicDataList.Where(x => x.addTime < t).OrderByDescending(x => x.addTime).FirstOrDefault();

                    //30分钟前所属主题最大时间的list加进来
                    var privateDataList_HMTC_MAX = new List<tPublicAnalogData>();
                    var privateDataList_HMTC_topiclist = publicDataList.GroupBy(x => x.Topic).ToList();
                    foreach (var item in privateDataList_HMTC_topiclist)
                    {
                        var top = publicDataList.Where(x => x.addTime < t && x.Topic == item.Key).OrderByDescending(x => x.addTime).FirstOrDefault();
                        if (top != null) privateDataList_HMTC_MAX.Add(top);
                    }


                    publicDataList = publicDataList.Where(x => t <= x.addTime && x.addTime < t.AddMinutes(30)).ToList();

                    if (privateDataList_HMTC_MAX.Count != 0)
                    {
                        publicDataList.AddRange(privateDataList_HMTC_MAX);
                    }
                }
            }
            return publicDataList;
        }

        /// <summary>
        /// 获取单个机组部分analog数据
        /// </summary>
        /// <param name="sn"></param>
        /// <param name="t"></param>
        /// <param name="Interval"></param>
        /// <returns></returns>
        private async static Task<List<tAnalogData>> get_privateDataList(string sn, DateTime t,string powerStationNo)
        {
            List<tAnalogData> privateDataList = new List<tAnalogData>();
            var topic = $"/{powerStationNo}/";
            using (var conn = db.CreateDeviceDb())
            {
                if ("wsr".Equals(sn))
                {
                    //WSR系列机组模拟量添加至统计list
                    var q =  conn.tAnalogData_WSR.Where(x => x.addTime >= t.AddMinutes(-30)  && x.addTime < t.AddMinutes(30) && x.Topic.Contains(topic));
                    var privateDataList_WSR = await q.ToListAsync();
                    //30分钟前所属主题最大时间的list加进来
                    var privateDataList_MAX = new List<tAnalogData_WSR>();
                    var privateDataList_topiclist = privateDataList_WSR.GroupBy(x => x.Topic).ToList();
                    foreach (var item in privateDataList_topiclist)
                    {
                        var top = item.Where(x => x.addTime < t).OrderByDescending(x => x.addTime).FirstOrDefault();
                        if (top != null) privateDataList_MAX.Add(top);
                    }
                    privateDataList_WSR = privateDataList_WSR.Where(x =>  x.addTime>= t && x.addTime < t.AddMinutes(30)).ToList();
                    if (privateDataList_MAX.Count != 0)
                    {
                        privateDataList_WSR.AddRange(privateDataList_MAX);
                    }

                    var privateDataList1 = privateDataList_WSR.Select(item =>
                    {
                        return new tAnalogData
                        {
                            addTime = item.addTime,
                            Topic = item.Topic,
                            analog9 = item.analog9,
                            analog10 = item.analog10,
                            analog31 = item.analog31,
                            analog32 = item.analog32,
                            analog82 = item.analog82,
                        };
                    });
                    privateDataList.AddRange(privateDataList1);
                }
                else if ("YKF1".Equals(sn))
                {
                    //WSR系列机组模拟量添加至统计list
                    var privateDataList_YKF1 = await conn.tAnalogData_YKF1.Where(x => t.AddMinutes(-30) <= x.addTime && x.addTime < t.AddMinutes(30) && x.Topic.Contains(topic)).ToListAsync();

                    //30分钟前电度数最大那一条加进来
                    //var privateDataList_YKF1_MAX =  privateDataList_YKF1.Where(x => x.addTime < t).OrderByDescending(x => x.addTime).FirstOrDefault();


                    //30分钟前所属主题最大时间的list加进来
                    var privateDataList_YKF1_MAX = new List<tAnalogData_YKF1>();
                    var privateDataList_YKF1_topiclist= privateDataList_YKF1.GroupBy(x => x.Topic).ToList();
                    foreach (var item in privateDataList_YKF1_topiclist) {
                        var top = privateDataList_YKF1.Where(x => x.addTime < t && x.Topic == item.Key).OrderByDescending(x => x.addTime).FirstOrDefault();
                        if (top != null) privateDataList_YKF1_MAX.Add(top);
                    }

                    privateDataList_YKF1 = privateDataList_YKF1.Where(x => t <= x.addTime && x.addTime < t.AddMinutes(30)).ToList();

                    if (privateDataList_YKF1_MAX.Count != 0)
                    {
                        privateDataList_YKF1.AddRange(privateDataList_YKF1_MAX);
                    }
                    var privateDataList1 = privateDataList_YKF1.Select(item =>
                    {
                        return new tAnalogData
                        {
                            addTime = item.addTime,
                            Topic = item.Topic,
                            analog9 = item.analog9,
                            analog31 = item.analog31,
                            analog32 = item.analog32,
                            analog82 = item.analog82
                        };
                    });
                    privateDataList.AddRange(privateDataList1);
                }
                else if ("YKF2".Equals(sn))
                {
                    //WSR系列机组模拟量添加至统计list
                    var privateDataList_YKF2 = await conn.tAnalogData_YKF2.Where(x => t.AddMinutes(-30) <= x.addTime && x.addTime < t.AddMinutes(30) && x.Topic.Contains(topic)).ToListAsync();

                    //30分钟前电度数最大那一条加进来
                    //var privateDataList_YKF2_MAX = privateDataList_YKF2.Where(x => x.addTime < t).OrderByDescending(x => x.addTime).FirstOrDefault();

                    //30分钟前所属主题最大时间的list加进来
                    var privateDataList_YKF2_MAX = new List<tAnalogData_YKF2>();
                    var privateDataList_YKF2_topiclist = privateDataList_YKF2.GroupBy(x => x.Topic).ToList();
                    foreach (var item in privateDataList_YKF2_topiclist)
                    {
                        var top = privateDataList_YKF2.Where(x => x.addTime < t && x.Topic == item.Key).OrderByDescending(x => x.addTime).FirstOrDefault();
                        if (top != null) privateDataList_YKF2_MAX.Add(top);
                    }


                    privateDataList_YKF2 = privateDataList_YKF2.Where(x => t <= x.addTime && x.addTime < t.AddMinutes(30)).ToList();
                    if (privateDataList_YKF2_MAX.Count != 0)
                    {
                        privateDataList_YKF2.AddRange(privateDataList_YKF2_MAX);
                    }
                    var privateDataList1 = privateDataList_YKF2.Select(item =>
                    {
                        return new tAnalogData
                        {
                            addTime = item.addTime,
                            Topic = item.Topic,
                            analog9 = item.analog9,
                            analog31 = item.analog31,
                            analog32 = item.analog32,
                            analog82 = item.analog82
                        };
                    });
                    privateDataList.AddRange(privateDataList1);
                }
                else if ("XAFD".Equals(sn))
                {
                    //WSR系列机组模拟量添加至统计list
                    var privateDataList_YKF2 = await conn.tAnalogData_XAFD.Where(x => t.AddMinutes(-30) <= x.addTime && x.addTime < t.AddMinutes(30) && x.Topic.Contains(topic)).ToListAsync();

                    //30分钟前所属主题最大时间的list加进来
                    var privateDataList_YKF2_MAX = new List<tAnalogData_XAFD>();
                    var privateDataList_YKF2_topiclist = privateDataList_YKF2.GroupBy(x => x.Topic).ToList();
                    foreach (var item in privateDataList_YKF2_topiclist)
                    {
                        var top = privateDataList_YKF2.Where(x => x.addTime < t && x.Topic == item.Key).OrderByDescending(x => x.addTime).FirstOrDefault();
                        if (top != null) privateDataList_YKF2_MAX.Add(top);
                    }
                    privateDataList_YKF2 = privateDataList_YKF2.Where(x => t <= x.addTime && x.addTime < t.AddMinutes(30)).ToList();
                    if (privateDataList_YKF2_MAX.Count != 0)
                    {
                        privateDataList_YKF2.AddRange(privateDataList_YKF2_MAX);
                    }


                    var privateDataList1 = privateDataList_YKF2.Select(item =>
                    {
                        return new tAnalogData
                        {
                            addTime = item.addTime,
                            Topic = item.Topic,
                            analog31 = item.analog31,
                            analog32 = item.analog32,
                            analog82 = item.analog82
                        };
                    });
                    privateDataList.AddRange(privateDataList1);
                }
                else if (sn == "HMTC")
                {
                    privateDataList = await conn.tAnalogData.Where(x => t <= x.addTime && x.addTime < t.AddMinutes(30)).ToListAsync();
                }
            }
            return privateDataList;
        }


        
        /// <summary>
        /// 时段发电量
        /// </summary>
        /// <param name="publicAnalogDatas"></param>
        /// <param name="deviceTopic"></param>
        /// <param name="groupName"></param>
        /// <param name="typeTimeItem"></param>
        /// <returns></returns>
        public static decimal GenerateElctricityTypeTimeByUnit_new(List<tAnalogData> analogDatas, string deviceTopic, string groupName, vGenerateElctricityTypeTime typeTimeItem, string deviceSN, decimal powerRate = 1, decimal salePowerRate = 1)
        {
            var q = analogDatas.Where(x => typeTimeItem.timeStart <= x.addTime && x.addTime <= typeTimeItem.timeEnd);
            if (q.Any() == false) return 0;
            if (groupName == "1#")
            {
                //计算当前时段每个机组的发电增量
                var group_analog = q.GroupBy(x => x.Topic);
               
                decimal countPower = 0;
                foreach (var group in group_analog)
                {
                    var group_max = group.MaxOrDefault(x => x.analog82)??0;
                    var group_min = group.Where(x => x.analog82 > 0).MinOrDefault(x => x.analog82)??0;
                    countPower += (group_max - group_min);
                    //Console.WriteLine("时间段"+typeTimeItem.timeStart+"--"+typeTimeItem.timeEnd +group.Key+"..."+(group_max - group_min));
                }
              
                return (countPower) * powerRate;
            }
            return 0;
        }

    }
}
